// Copyright (C) Calum Grant 2008

#include "cppscript"
#include "dynamic/extensions.hpp"

static_call( register_pickle_type( cmp_double, 0.0 ) );

namespace dynamic
{
	namespace types
	{
		/// Implements a double.
		/** \ingroup impl */
		class double_impl : public dynamic::var_impl
		{
			double d;
		public:
			double_impl(double d) : d(d) { }

			double_impl(const double_impl&d) : d(d.d) { }

			void output(ostream & ss)
			{
				ss << d;
			}

			void output(wostream & ss)
			{
				ss << d;
			}

			std::string class_name() { return "double"; }

			int as_int()
			{
				return int(d);
			}

			double as_double()
			{
				return d;
			}

			bool as_bool() 
			{ 
				return d != 0.0; 
			}

			var op_neg()
			{
				return -d;
			}

			var op_add(const var & v)
			{
				return d + v.as_double();
			}

			var op_sub(const var & v)
			{
				return d - v.as_double();
			}

			var op_mul(const var & v)
			{
				return d * v.as_double();
			}

			var op_div(const var & v)
			{
				return d / v.as_double();
			}

			void op_inc() { ++d; }
			void op_dec() { --d; }

			var_cmp_index comparison_index() { return cmp_double; }

			var_cmp_result compare2(const var & v)
			{
				double diff = d - v.as_double();
				if(diff<0) return cmp_lt;
				if(diff>0) return cmp_gt;
				return cmp_equal;
			}

			void copy_to(void * dest) const
			{
				new(dest) double_impl(*this);
			}

			void assign_add(const var & v)
			{
				d += v.as_double();
			}

			void assign_sub(const var & v)
			{
				d -= v.as_double();
			}

			void assign_mul(const var & v)
			{
				d *= v.as_double();
			}

			void assign_div(const var & v)
			{
				d /= v.as_double();
			}

			void pickle(pickler & p)
			{
				p.write_object_type(cmp_double);
				p.write_double(d);
			}

			void unpickle(unpickler & u)
			{
				d = u.read_double();
			}
		};
	}
}


var::var(double d) : m_variant(types::double_impl(d))
{
}
